#!/usr/bin/python
'''
Created on Nov 2, 2011

@author: wolas
'''
#DATAFORMAT
#|PHONE_ID probably IP adress|TIMESTAMP|Acelerometer X| aY| aZ|
# rotator has diferent timestamp so same timestamp cant be used for both... 

import socket
import time
import threading
import pygtk
import gtk
import gobject
pygtk.require("2.0") 
#from collections import deque
from Calculations import Calculate

HOST = ''
PORT = 44444
TIMEOUT = 5 #seconds
CONNECTION_LIMIT = 16
HELLO_ANDROID = 'hello_android'
HELLO_SERVER = 'hello_server'
SEND_NOW_MSG = 'send_now' #message over network
STOP_NOW_MSG = 'stop_now'
SEND_MORE_MSG = 'send_more'
IDLE_MSG = 'idle'
INTRO_MSG = '!!'
OUTRO_MSG = '??'
#  control
SEND_NOW = False    #pradeti siuntima
#STOP_NOW = False    #nustoti siusti, bet susijungimas nenutraukiamas.
CONNECT = False     #palaikyti susijungima

#fifoData = deque()

calc=Calculate()
class Loop(threading.Thread):
    
    def __init__(self):
        threading.Thread.__init__(self)
        
    def run (self):
        print 'trying to connect'
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server_socket.settimeout(TIMEOUT)
        server_socket.bind((HOST, PORT))
        server_socket.listen(CONNECTION_LIMIT)
        while 1:
            if CONNECT == False :
                print "stoping accepting incoming connections"
                break
            try:
                conn, addr = server_socket.accept()
                print 'Connected by', addr
                th = SocketThreadControl(conn, addr)
                th.start()
                print "paleidau socketa freda"
            except socket.timeout: 
                print str(TIMEOUT) + "s prisijungimas timeoutino!"
            except :
                print "unknown error"
        
        server_socket.shutdown(2) #stop reading and writing
        server_socket.close()
        return

class GUI(object):
    
    #th=Loop()
    
    def __init__(self):
        gobject.threads_init() # fake error
        builder = gtk.Builder()
        builder.add_from_file("../GUI.glade")
        builder.connect_signals(self)
        self.window = builder.get_object("window")
        self.window.show()

    def on_connect_activate(self,widget,data=None):
        global CONNECT
        CONNECT = True
        try :
            if self.th.isAlive() :
                print "not starting thread twice"
            else:
                self.th=Loop()
                self.th.start()    
        except:
            self.th=Loop()
            self.th.start()

    
    def on_disconnect_activate(self,widget,data=None):
        global CONNECT
        global SEND_NOW
        CONNECT = False
        SEND_NOW = False
        
    def on_stop_now_clicked(self,widget,data=None):
        global SEND_NOW
        SEND_NOW = False
    
    def on_send_now_clicked(self,widget,data=None):
        global SEND_NOW
        SEND_NOW = True    
        
    def on_window_destroy(self, widget, data=None):
        print "i never ever was here"
        gtk.main_quit()

    def on_button_clicked(self, widget, data=None):
        gtk.main_quit()  


class SocketThreadControl(threading.Thread):
            
    def __init__(self, cl_socket, cl_adress):
        self.conn = cl_socket
        self.adress = cl_adress
        self.connected = True
        self.i=0
        threading.Thread.__init__(self)
        
    def __send_intro_msg(self):
        self.conn.send(INTRO_MSG) #tikrinti ar viskas tvarkoje!
    
    def __send_outro_msg(self):
        self.conn.send(OUTRO_MSG)
        
    def __send_length_msg(self, msg):
        length=len(msg)
        self.conn.send(str(length))
    
    def __send_cmd(self, cmd):
        self.__send_intro_msg()
        self.__send_length_msg(cmd)
        self.conn.send(cmd)
        self.__send_outro_msg()   
    
    def __handshake(self):
        data = self.conn.recv(1024)
        print HELLO_SERVER
        if  HELLO_SERVER == data:
            print "tai hello_server"
            count = self.conn.send(HELLO_ANDROID)
            if count != len(HELLO_ANDROID):
                return False
            else:
                data = self.conn.recv(1024)
                if data == "success" :
                    print " i did handshake!!!"
                    return True
        return False    
        
    def __receive(self):
        print "__receive"
        #  for i in range(1000):
        nr=''
        global fifoData
        global calc
        nr_type = 0
        arr= []
        send_back=50 #how many lines receive
        while True :
            data = self.conn.recv(4096)
            print "got datachunk size " + str(len(data))
            for i in range(len(data)):
                if data[i] == '\n':
                    print nr
                    if nr_type < 3 : # float
                        # arr[nr_type]=nr
                        arr.append(nr)
                        nr_type=nr_type+1
                    else:          #long
                        #arr[nr_type]=nr
                        arr.append(nr)
                        #DATA INSERTION HERE
                        #Calculation probably should here too
                        #                  self.cur.execute('INSERT INTO acc VALUES(?,?,?,?,?)'
                        #                        ,(self.i,arr[3],arr[0],arr[1],arr[2]))
                        #self.i data ID must be used in error correction, but not now :)
                        temp=[self.adress, arr[3], arr[0],arr[1],arr[2]]
                        calc.addData(temp)
                        #fifoData.append(temp) OLD
                        print "writed data NR is " + str(self.i)
                        del arr
                        arr=[]
                        if send_back<2:
                            print "receive finished"
                            return 1                    #<------ here function ends
                        nr_type=0;
                        self.i+=1
                        print "send_back is " + str(send_back)
                        send_back=send_back-1
                    nr=''
                else:
                    nr=nr+data[i]

    def __sql_do(self):
        pass        
    
    def __idle(self):
        self.__send_cmd(IDLE_MSG)
        #HACK <- shit code geos here
        data = self.conn.recv(1024)
        if data == "idling" :
            print "we are idling somehow..."
        else :
            print "WTF"
        time.sleep(1)
        
    def run (self):
        print "in run"
        #send_now = True
        #send_now = SEND_NOW #send_now is just for not sending hello twice.
        #stop_now = STOP_NOW
        if not self.__handshake() : #basically checking if this is phone
            print "cant handshake!!!"
            self.connected = False
        #send_now=True #DELETE ME
#     stop_now=False#DELETE ME
        while self.connected:
            if CONNECT == False :
                print "closing active connection of " + str(self.adress)
                self.connected = False
                #send_now = False
                self.__send_cmd(STOP_NOW_MSG)
                #break # maybe first should send STOP_NOW MSG
            elif SEND_NOW == False:  #sending idle message, keeping connection alive.
                self.__idle()
            #elif send_now == True and SEND_NOW == True: #user clicked to send data sending SEND_NOW
            #    self.__send_cmd(SEND_NOW_MSG)
            #    send_now = False
            #elif send_now == False and SEND_NOW == False: #user clicked to stop sending data
            #    send_now = True
            #    self.__send_cmd(STOP_NOW_MSG)        
            #elif send_now == False and SEND_NOW == True: #receiving data
            else:
                print "prisijunges recievinammmm"
                self.__send_cmd(SEND_MORE_MSG)
                self.__receive()
                #self.__send_cmd(SEND_MORE_MSG) # WRONG asks for more data even when dont know if it needs
                #global calc #delete this
                #print fifoData # skaitymas is saraso ir kartu pasalinamas tas pats yrasas
                calc.dump() #delete that
                #print temp[0]
                #arba
                #print fifoData[0][1] bet tada neistrins skaitomo iraso.
                #               self.ch = self.conn.recv(1024)
                #              print len(self.ch)
                #             print self.ch
        
        print "pabaiga"
        self.conn.shutdown(2)
        self.conn.close()

if __name__ == "__main__":
    app = GUI()
    gtk.main()
        
        

                


